package com.ruoyi.recycle.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.recycle.domain.BillRecord;
import com.ruoyi.recycle.domain.IntegralConfig;
import com.ruoyi.recycle.domain.MerchantManagement;
import com.ruoyi.recycle.dto.MerchantBillRecordQueryDTO;
import com.ruoyi.recycle.exception.BusinessException;
import com.ruoyi.recycle.mapper.BillRecordMapper;
import com.ruoyi.recycle.service.BillRecordService;
import com.ruoyi.recycle.service.IIntegralConfigService;
import com.ruoyi.recycle.service.IMerchantManagementService;
import com.ruoyi.recycle.vo.BillRecordVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;

@Service
public class BillRecordServiceImpl extends ServiceImpl<BillRecordMapper, BillRecord> implements BillRecordService {

    @Autowired
    private IMerchantManagementService merchantManagementService;
    @Autowired
    private IIntegralConfigService configService;


    @Override
    public BillRecordVO billStatistics(MerchantBillRecordQueryDTO queryDTO) {
        final LambdaQueryWrapper<BillRecord> queryWrapper = Wrappers.lambdaQuery(new BillRecord())
                .eq(BillRecord::getAccount, queryDTO.getAccount()).orderByDesc(BillRecord::getCreateTime);
        if (queryDTO.getSearchTimeBegin() != null) {
            queryWrapper.ge(BillRecord::getCreateTime, queryDTO.getSearchTimeBegin());
        }
        if (queryDTO.getSearchTimeEnd() != null) {
            queryWrapper.le(BillRecord::getCreateTime, queryDTO.getSearchTimeEnd());
        }
        final MerchantManagement merchant = merchantManagementService.getOne(Wrappers.lambdaQuery(new MerchantManagement())
                .eq(MerchantManagement::getMerchantNumber, queryDTO.getAccount()));
        Assert.isTrue(Objects.nonNull(merchant), () -> new BusinessException("请输入对应账号来查询相关信息"));
        final List<BillRecord> housekeepingBillRecords = getBaseMapper()
                .getHousekeepingBillRecord(merchant.getId());
        final List<BillRecord> records = list(queryWrapper);
        List<BillRecord> outputRecords = null;
        List<BillRecord> incomeRecords = new ArrayList<>();
        Double incomeAmount = null;
        Double outputAmount = null;
        if (CollUtil.isNotEmpty(records)) {
            incomeRecords = records.stream()
                    .filter(i -> i.getType() == 0 || i.getType() == 1)
                    .collect(Collectors.toList());
            incomeAmount = incomeRecords.stream().flatMapToDouble(b -> DoubleStream.of(b.getIncome().doubleValue())).sum();
            outputRecords = records.stream()
                    .filter(o -> o.getType() == 3 || o.getType() == 2)
                    .collect(Collectors.toList());
            outputAmount = outputRecords.stream()
                    .flatMapToDouble(b -> DoubleStream.of(b.getOutput().doubleValue())).sum();
            if (CollUtil.isNotEmpty(housekeepingBillRecords)) {
                final double hkOrderSum = housekeepingBillRecords.stream().filter(hk -> Objects.nonNull(hk.getIncome()))
                        .flatMapToDouble(hk -> DoubleStream.of(hk.getIncome().doubleValue())).sum();
                final IntegralConfig config = configService
                        .getOne(Wrappers.lambdaQuery(new IntegralConfig()).eq(IntegralConfig::getType, "1"));
                final BigDecimal blueCoin = BigDecimal.valueOf(hkOrderSum).multiply(BigDecimal.valueOf(config.getIntegral()));
                incomeAmount = incomeAmount + blueCoin.doubleValue();
            }
        }
        incomeRecords.addAll(housekeepingBillRecords);
        return new BillRecordVO()
                .setIncomeRecords(incomeRecords)
                .setOutputRecords(outputRecords)
                .setOutputAmount(outputAmount)
                .setIncomeAmount(incomeAmount);
    }


    @Override
    public Long selectCountOutIntegral(Long clientId, Date searchTime) {
        return getBaseMapper().selectCountOutIntegral(clientId, searchTime);
    }

    @Override
    public Long selectCountInIntegral(Long clientId, Date searchTime) {
        return getBaseMapper().selectCountInIntegral(clientId, searchTime);
    }

    @Override
    public List<BillRecord> getBillRecordList(Long clientId, Date searchTime) {
        return getBaseMapper().getBillRecordList(clientId, searchTime);
    }

    @Override
    public List<BillRecord> selectInSalesmanBill(String signTime, Long salesmanId) {
        return getBaseMapper().selectInSalesmanBill(signTime, salesmanId);
    }

    @Override
    public List<BillRecord> selectOutSalesmanBill(String signTime, Long salesmanId) {
        return getBaseMapper().selectOutSalesmanBill(signTime, salesmanId);
    }


}

